/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bean.session;

import entity.CompletedGoodsEntity;
import entity.ProductQuantityPriceEntity;
import entity.SaleOrderReportEntity;
import entity.SalesOrderEntity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import type.Month;
import type.SalesOrderType;

/**
 *
 * @author wei
 */
@Stateless
public class SaleOrderReportEntityFacade extends AbstractFacade<SaleOrderReportEntity> {
    @PersistenceContext(unitName = "MacTeam-warPU")
    private EntityManager em;

    protected EntityManager getEntityManager() {
        return em;
    }

    public SaleOrderReportEntityFacade() {
        super(SaleOrderReportEntity.class);
    }
    
    @Schedule(dayOfMonth="1", hour="0", minute="0")
    public void createSchedule() {
        SaleOrderReportEntity normreport1 = new SaleOrderReportEntity();
        SaleOrderReportEntity normreport2 = new SaleOrderReportEntity();
        SaleOrderReportEntity normreport3 = new SaleOrderReportEntity();
        SaleOrderReportEntity normreport4 = new SaleOrderReportEntity();
        SaleOrderReportEntity promoreport1 = new SaleOrderReportEntity();
        SaleOrderReportEntity promoreport2 = new SaleOrderReportEntity();
        SaleOrderReportEntity promoreport3 = new SaleOrderReportEntity();
        SaleOrderReportEntity promoreport4 = new SaleOrderReportEntity();
        
        createReportEntity(normreport1, promoreport1, "Classic Nutri Bar (Nuts)");
        createReportEntity(normreport2, promoreport2, "Classic Nutri Bar (Fruits)");
        createReportEntity(normreport3, promoreport3, "Premium Power Bar (Chocolate Nuts)");
        createReportEntity(normreport4, promoreport4, "Premium Power Bar (Redcurrant Fruits)");
    }
    
    public ArrayList<SalesOrderEntity> getAllNormSalesOrder() {
        ArrayList salesOrder = new ArrayList<SalesOrderEntity>();
        Query query = em.createQuery("SELECT s FROM SalesOrder s WHERE s.promotion != 'true'");
        for (Object o : query.getResultList()) {
            SalesOrderEntity s = new SalesOrderEntity();
            s = (SalesOrderEntity) o;
            salesOrder.add(s);
        }
        return salesOrder;
    }
    
    public ArrayList<SalesOrderEntity> getAllPromoSalesOrder() {
        ArrayList salesOrder = new ArrayList<SalesOrderEntity>();
        Query query = em.createQuery("SELECT s FROM SalesOrder s WHERE s.promotion != 'false'");
        for (Object o : query.getResultList()) {
            SalesOrderEntity s = new SalesOrderEntity();
            s = (SalesOrderEntity) o;
            salesOrder.add(s);
        }
        return salesOrder;
    }
    
    public ArrayList<SalesOrderEntity> getAllSalesOrderThisMonth(ArrayList<SalesOrderEntity> salesOrders) {
        Calendar startCal = Calendar.getInstance();
        Calendar endCal = Calendar.getInstance();
        int year =  startCal.get(Calendar.YEAR);
        int startMonth = startCal.get(Calendar.MONTH) - 1;
        int endMonth = endCal.get(Calendar.MONTH);
        int startDate = 1;
        int endDate = 1;
        startCal.clear();
        endCal.clear();
        startCal.set(Calendar.YEAR, year);
        startCal.set(Calendar.MONTH, startMonth);
        startCal.set(Calendar.DATE, startDate);
        endCal.set(Calendar.YEAR, year);
        endCal.set(Calendar.MONTH, endMonth);
        endCal.set(Calendar.DATE, endDate);
        Date startDay = startCal.getTime();
        Date endDay = endCal.getTime();
        System.out.println(startDay + " " + endDay);
        
        ArrayList<SalesOrderEntity> salesOrder = salesOrders;
        ArrayList salesOrderThisMonth = new ArrayList<SalesOrderEntity>();
        for(int i = 0; i < salesOrder.size(); i++) {
            if (salesOrder.get(i).getCreatedAt().after(startDay) && salesOrder.get(i).getCreatedAt().before(endDay))
                salesOrderThisMonth.add(salesOrder.get(i));
        }
        return salesOrderThisMonth;
    }
    
    public void createReportEntity(SaleOrderReportEntity normreport, SaleOrderReportEntity promoreport, String productName) {
        long quantity = 0;
        long id = 0;
        long promoquantity = 0;
        long promoid = 0;
        Calendar today = Calendar.getInstance();
        int year =  today.get(Calendar.YEAR );
        int month = today.get(Calendar.MONTH);
        
        ArrayList<SalesOrderEntity> salesOrder = getAllSalesOrderThisMonth(getAllNormSalesOrder());
        for (int i = 0; i < salesOrder.size(); i++) {
            ArrayList<ProductQuantityPriceEntity> pqp = new ArrayList<ProductQuantityPriceEntity>(salesOrder.get(i).getPurchaseOrder().getProductQuantityPrice());
            for (int j = 0; j < pqp.size(); j++) {
                if (pqp.get(j).getProduct().getProductName().equals(productName)) {
                    quantity = quantity + pqp.get(j).getQuantity();
                    if (id == 0)
                        id = pqp.get(j).getProduct().getId();
                }
            }
        }
        
        if (quantity != 0) {
            normreport.setProduct(getCompletedGoods(id));
            normreport.setQuantity(quantity);
            normreport.setType(SalesOrderType.normal);
            normreport.setYearOfSales(year);
            normreport.setMonthOfSales(Month.fromMonthNum(month));
            create(normreport);
        }
        
        ArrayList<SalesOrderEntity> promosalesOrder = getAllSalesOrderThisMonth(getAllPromoSalesOrder());
        for (int i = 0; i < promosalesOrder.size(); i++) {
            ArrayList<ProductQuantityPriceEntity> pqp = new ArrayList<ProductQuantityPriceEntity>(promosalesOrder.get(i).getPurchaseOrder().getProductQuantityPrice());
            for (int j = 0; j < pqp.size(); j++) {
                if (pqp.get(j).getProduct().getProductName().equals(productName)) {
                    promoquantity = promoquantity + pqp.get(j).getQuantity();
                    if (promoid == 0)
                        promoid = pqp.get(j).getProduct().getId();
                }
            }
        }

        if (promoquantity != 0) {
            promoreport.setProduct(getCompletedGoods(promoid));
            promoreport.setQuantity(promoquantity);
            promoreport.setType(SalesOrderType.promo);
            promoreport.setYearOfSales(year);
            promoreport.setMonthOfSales(Month.fromMonthNum(month));
            create(promoreport);
        }
    }
    
    public CompletedGoodsEntity getCompletedGoods(long id) {
        Query query = em.createQuery("SELECT c FROM CompletedGoods c WHERE c.id = " + id);
        CompletedGoodsEntity completedGoods = (CompletedGoodsEntity) query.getSingleResult();
        return completedGoods;
    }
    
    //    public ArrayList<SalesOrderEntity> promotionProduct() {
//        Calendar startCal = Calendar.getInstance();
//        Calendar endCal = Calendar.getInstance();
//        Date startDay = startCal.getTime();
//        Date endDay = endCal.getTime();
//        
//        ArrayList salesOrder = new ArrayList<SalesOrderEntity>();
//        
//        CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
//            javax.persistence.criteria.CriteriaQuery cq = builder.createQuery();
//////            Metamodel m = em.getMetamodel();
//////            EntityType<SalesOrderEntity> SalesOrderEntity = m.entity(SalesOrderEntity.class);
////            Root<DataObjectEntity> salesOrderRoot = cq.from(SalesOrderEntity.class);
////            cq.select(salesOrderRoot);
////            cq.where(builder.and(builder.between(salesOrderRoot.get("createdAt").as(Date.class), startDay, endDay)),
////                    builder.equal(salesOrderRoot.get("promotion"), true));

//            Root<PurchaseOrderEntity> purchaseOrder = cq.from(PurchaseOrderEntity.class);
//            Path<Object> path = purchaseOrder.get("salesOrder");
//            CriteriaQuery<Object> select = cq.select(purchaseOrder);
//            
//            Subquery<DataObjectEntity> subquery = cq.subquery(SalesOrderEntity.class);
//            Root<DataObjectEntity> salesOrderRoot = cq.from(SalesOrderEntity.class);
//            subquery.select(salesOrderRoot);
////            subquery.where(builder.and(builder.between(salesOrderRoot.get("createdAt").as(Date.class), startDay, endDay)),
////                    builder.equal(salesOrderRoot.get("promotion"), true));
//            subquery.where(builder.between(salesOrderRoot.get("createdAt").as(Date.class), startDay, endDay));
//            select.where(builder.in(path).value(subquery));
//   
//                      
//        for (Object o : getEntityManager().createQuery(cq).getResultList()) {
//            SalesOrderEntity s = new SalesOrderEntity();
//            s = (SalesOrderEntity) o;
//            System.out.println(s.getId());
//            salesOrder.add(s);
//        }
//        return salesOrder;
//    }
    
    public DataModel getAllSaleOrderReport() {
        Query query = em.createQuery("SELECT s FROM SaleOrderReport s WHERE s.archived!= 'true'");
        return new ListDataModel(query.getResultList());
    }
}
